package se.webbzon.oschi01.nbt;

import java.util.ArrayList;

import se.webbzon.oschi01.nbt.TagEvent.Action;

public class CompoundTag extends AbstractTag<Iterable<Tag<?>>> {
	
	private final TagRing<?> children;
	
	public CompoundTag(TagFactory<Iterable<Tag<?>>> factory, String tagName) {
		this(factory,tagName,(Tag<?>[]) null);
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public CompoundTag(TagFactory<Iterable<Tag<?>>> factory, String tagName, Tag<?>...children) {
		super(factory, tagName);
		this.children = new TagRing<Object>(this);
		if (children != null) {
			for (Tag child : children) {
				this.children.addSibling(child);
			}
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	boolean addTag(Tag<?> tag) {
		Tag t = tag;
		return children.addSibling(t,true);
	}
	
	@Override public boolean canAdopt(Tag<?> child) {
		return true;
	}
	
	@Override public long size() {
		long size = 0;
		TagSibling tag = children.getSibling();
		while (tag != children) {
			size += ((Tag<?>) tag).size();
			tag = tag.getSibling();
		}
		return size;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override public Iterable<Tag<?>> getValue() {
		Iterable i = children;
		return i;
	}
	
	@Override public boolean hasChildren() {
		return !children.isEmpty();
	}

	@Override public TagGeneration<?> getChildren() {
		return children;
	}


	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override public void setValue(Iterable<Tag<?>> value) {
		children.clear();
		ArrayList<Object> values = new ArrayList<Object>();
		int count = 0;
		for (Tag tag : value) {
			values.add(tag);
			children.addSibling(tag,true);
			count++;
		}
		if (count > 0) {
			int[] indicies = new int[count];
			for (int i = 0; i < count; i++)
				indicies[i] = i;
			broadcastEvent(new TagEvent(this,Action.CHILD_ADDED,indicies,values.toArray()));
		}
	}

	@SuppressWarnings("unchecked")
	@Override public Class<Iterable<Tag<?>>> getValueClass() {
		return (Class<Iterable<Tag<?>>>) children.getClass();
	}

	@Override public CompoundTag clone() {
		CompoundTag copy = new CompoundTag(getFactory(),this.toString());
		for (Tag<?> child : children)
			copy.addTag(child.clone());
		return copy;
	}

}
